﻿/*
* 创建者：LIYINFAI
* 创建时间：2023/12/15 11:40:00
* 描述：
* --------------------------------------
* 修改说明：
* --------------------------------------
*/
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Text;
using static NPOI.HSSF.Util.HSSFColor;

namespace CommonLibrary
{
    /// <summary>
    /// HIOKIST5520串口配置
    /// </summary>
    public class HIOKIST5520ComParam : ComParameter
    {
        /// <summary>
        /// 触发地址与结果
        /// </summary>
        [Description("触发地址与结果")]
        [JsonProperty(PropertyName = "PLCEntities")]
        public List<HIOKIST5520PLCEntity> PLCEntities = new List<HIOKIST5520PLCEntity>();
        /// <summary>
        /// 描述信息
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            return CommonHelper.GetObjectString(this);
        }
    }
    /// <summary>
    /// HIOKIST5520TCP配置
    /// </summary>
    public class HIOKIST5520TcpParam : TcpParameter
    {
        /// <summary>
        /// 触发地址与结果
        /// </summary>
        [Description("触发地址与结果")]
        [JsonProperty(PropertyName = "PLCEntities")]
        public List<HIOKIST5520PLCEntity> PLCEntities = new List<HIOKIST5520PLCEntity>();
        /// <summary>
        /// 描述信息
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            return CommonHelper.GetObjectString(this);
        }
    }
    /// <summary>
    /// 数据通知代理
    /// </summary>
    /// <param name="value"></param>
    /// <param name="judgeString"></param>
    public delegate void NotifyHIOKIST5520HelperJobDelegate(float value, string judgeString);
    /// <summary>
    /// HIOKIST5520帮助类
    /// </summary>
    public class HIOKIST5520Helper : BaseHelper
    {
        /// <summary>
        /// TCP配置文件
        /// </summary>
        static string autoTcpHIOKIST5520ConfigPath = Path.Combine(CommonHelper.COMMON_CONFIG_DIR, "HIOKIST5520TCPConfig.json");
        /// <summary>
        /// 串口配置文件（自动HIOKIST5520）
        /// </summary>
        static string autoComHIOKIST5520ConfigPath = Path.Combine(CommonHelper.COMMON_CONFIG_DIR, "HIOKIST5520ComConfig.json");
        #region tcp auto
        /// <summary>
        /// 获取TCPHIOKIST5520配置，返回List对象
        /// </summary>
        /// <returns></returns>
        /// <exception cref="Exception"></exception>
        public static List<HIOKIST5520TcpParam> GetAutoHIOKIST5520TCPConfig()
        {
            return CommonHelper.GetJsonListFromFile<HIOKIST5520TcpParam>(autoTcpHIOKIST5520ConfigPath);
        }
        /// <summary>
        /// 保存TCP配置内容
        /// </summary>
        /// <param name="list"></param>
        public static void SaveAutoHIOKIST5520TCPConfig(List<HIOKIST5520TcpParam> list)
        {
            CommonHelper.SaveToJsonFile(list, autoTcpHIOKIST5520ConfigPath);
        }
        #endregion
        #region auto com
        /// <summary>
        /// 获取串口配置内容（自动HIOKIST5520）
        /// </summary>
        /// <returns></returns>
        public static List<HIOKIST5520ComParam> GetAutoHIOKIST5520ComConfig()
        {
            return CommonHelper.GetJsonListFromFile<HIOKIST5520ComParam>(autoComHIOKIST5520ConfigPath);
        }
        /// <summary>
        /// 保存串口配置内容（自动HIOKIST5520）
        /// </summary>
        /// <param name="list"></param>
        public static void SaveAutoHIOKIST5520ComConfig(List<HIOKIST5520ComParam> list)
        {
            CommonHelper.SaveToJsonFile(list, autoComHIOKIST5520ConfigPath);
        }
        #endregion
        private Dictionary<string, short> mJudgeResults = new Dictionary<string, short>() {
            { "OFF",0 },//判定功能为OFF
            { "NOCOMP",3 },//未判定
            { "DELAY",4 },//响应时间定时器启用中
            { "PASS",1 },//判定基准以内
            { "U.FAIL",5 },//上限值<=测量值
            { "LFAIL",6 },//下限值>=测量值
            { "ULFAIL",7 },//不能判定（上限值或下限值偏离量程范围）
        };
        /// <summary>
        /// 状态检测
        /// </summary>
        private void StatusHandler(bool isOK)
        {
            var param = new HIOKIStatusExcuteEntity()
            {
                IsOK = isOK,
                StatusAddress = this.StatusAddress
            };
            #region  PLC
            PluginManager.Instance.Excute(this.Name, "HIOKIST5520_STATUS_PLC", CommonHelper.GetJsonString(param, Formatting.None));
            #endregion
        }
        /// <summary>
        /// 构造函数
        /// </summary>
        public HIOKIST5520Helper()
        {
            this.CustomSelfExecuteHandler = () =>
            {
                try
                {
                    if (!string.IsNullOrWhiteSpace(this.StatusAddress))
                    {
                        if (this.IsConnected)
                        {
                            var deviceInfo = GetDeviceInfo();
                            var isOK = !string.IsNullOrWhiteSpace(deviceInfo.manufacturer) ? true : false;
                            StatusHandler(isOK);
                        }
                        else
                        {
                            StatusHandler(false);
                        }
                    }
                }
                catch (Exception ex)
                {
                    LogHelper.Error(ex);
                }
            };
        }
        #region 每个Helper特定的参数
        /// <summary>
        /// 通讯超时时间，默认1000毫秒
        /// </summary>
        public override int CommunicationTimeout => BusinessConfig.Instance().ST5520Timeout;
        /// <summary>
        /// 获取测量值与判定结果命令
        /// </summary>
        public const string MEASURE_VALUE_RESULT_COMMAND = ":MEASure:RESult?\r\n";
        /// <summary>
        /// 获取仪器信息
        /// </summary>
        public const string DEVICE_INFO_COMMAND = "*IDN?\r\n";
        /// <summary>
        /// 数据通知处理
        /// </summary>
        public NotifyHIOKIST5520HelperJobDelegate NotifyHIOKIST5520HelperJob { get; set; } = null;
        #endregion
        /// <summary>
        /// PLC业务
        /// </summary>
        /// <param name="value"></param>
        /// <param name="judgeResult"></param>
        /// <param name="judgeString"></param>
        /// <param name="plcEntity"></param>
        private void BusinessHandler(HIOKIST5520PLCEntity plcEntity, float value, short judgeResult, string judgeString)
        {
            if (plcEntity != null)
            {
                var param = new HIOKIST5520ExcuteEntity()
                {
                    PlcEntity = plcEntity,
                    MeasureResult = value,
                    JudgeResult = judgeString,
                    JudgeValueResult = judgeResult
                };
                #region  PLC
                PluginManager.Instance.Excute(this.Name, "HIOKIST5520_RESULT_PLC", CommonHelper.GetJsonString(param, Formatting.None));
                #endregion                
                if (this.NotifyHIOKIST5520HelperJob != null)
                {
                    this.NotifyHIOKIST5520HelperJob(value, judgeString);
                }
            }
        }
        /// <summary>
        /// 串口方式获取测量值
        /// </summary>
        /// <returns></returns>
        private string GetComMeasureValueResult()
        {
            return RunComCommand(MEASURE_VALUE_RESULT_COMMAND);
        }
        /// <summary>
        /// TCP方式获取测量值
        /// </summary>
        /// <returns></returns>
        private string GetTcpMeasureValueResult()
        {
            return RunTcpCommand(MEASURE_VALUE_RESULT_COMMAND);
        }
        private static char[] SPLIT_CHAR_ARRAY = new char[] { ',' };

        /// <summary>
        /// 获取测量值，判定结果（单位 MΩ）
        /// </summary>
        /// <returns></returns>
        public (float value, short judgeResult, string judgeString) GetMeasureValueResult()
        {
            float value = 0;
            short judgeResult = 0;
            string judgeString = string.Empty;
            string result = this.CommunicationType == ECommunicationType.SERIAL ? GetComMeasureValueResult() : GetTcpMeasureValueResult();
            result = CommonHelper.RemoveEnterString(result);
            if (string.IsNullOrWhiteSpace(result))
            {
                StatusHandler(false);
            }
            result = string.IsNullOrWhiteSpace(result) ? "0,OFF" : result;
            if (!string.IsNullOrWhiteSpace(result) && result.Contains(","))
            {
                string[] parts = result.Split(SPLIT_CHAR_ARRAY, StringSplitOptions.RemoveEmptyEntries);
                if (parts != null && parts.Length > 0)
                {
                    if (float.TryParse(parts[0], out value))
                    {
                        value /= 1000.0f;
                    }
                }

                judgeString = parts != null && parts.Length > 1 ? parts[1] : "OFF";
                if (this.mJudgeResults.ContainsKey(judgeString))
                {
                    judgeResult = this.mJudgeResults[judgeString];
                }
            }
            return (value, judgeResult, judgeString);
        }


        /// <summary>
        /// 串口方式获取仪器信息
        /// </summary>
        /// <returns></returns>
        private string GetComDeviceInfo()
        {
            return RunComCommand(DEVICE_INFO_COMMAND);
        }
        /// <summary>
        /// TCP方式获取仪器信息
        /// </summary>
        /// <returns></returns>
        private string GetTcpDeviceInfo()
        {
            return RunTcpCommand(DEVICE_INFO_COMMAND);
        }
        /// <summary>
        /// 获取仪器信息
        /// PC>*IDN?
        /// ST5520>HIOKI,ST5520,000012345,V1.00
        /// 
        /// 制造商: HIOKI
        /// 型号: ST5520
        /// 序号：000012345
        /// 版本: V1.00
        /// </summary>
        /// <returns></returns>
        public (string manufacturer, string model, string serialNo, string version) GetDeviceInfo()
        {
            string manufacturer = string.Empty, model = string.Empty, serialNo = string.Empty, version = string.Empty;
            string result = this.CommunicationType == ECommunicationType.SERIAL ?
                GetComDeviceInfo() : GetTcpDeviceInfo();
            result = CommonHelper.RemoveEnterString(result);
            if (string.IsNullOrWhiteSpace(result))
            {
                StatusHandler(false);
            }
            result = string.IsNullOrWhiteSpace(result) ? string.Empty : result;
            if (!string.IsNullOrWhiteSpace(result) && result.Contains(","))
            {

                string[] parts = result.Split(SPLIT_CHAR_ARRAY, StringSplitOptions.RemoveEmptyEntries);
                if (parts != null && parts.Length > 0)
                {
                    manufacturer = parts[0];
                }
                if (parts != null && parts.Length > 1)
                {
                    model = parts[1];
                }
                if (parts != null && parts.Length > 2)
                {
                    serialNo = parts[2];
                }
                if (parts != null && parts.Length > 3)
                {
                    version = parts[3];
                }
            }
            return (manufacturer, model, serialNo, version);
        }

        /// <summary>
        /// 业务处理
        /// </summary>
        /// <param name="handlerName"></param>
        /// <param name="handlerType"></param>
        /// <param name="otherAddress"></param>
        /// <param name="otherData"></param>
        public override void RealHandler(string handlerName, EHandlerType handlerType, object otherAddress, object otherData)
        {
            this.RealShowMessage($"【{this.Name}】{handlerName}");
            float value = 0;
            short judgeResult = 0;
            string judgeString = string.Empty;
            if (this.IsConnected)
            {
                Stopwatch stopwatch = Stopwatch.StartNew();
                try
                {
                    var result = GetMeasureValueResult();
                    value = result.value;
                    judgeResult = result.judgeResult;
                    judgeString = result.judgeString;
                }
                catch (Exception ex)
                {
                    LogHelper.Error(ex);
                }
                finally
                {
                    HIOKIST5520PLCEntity entity = otherAddress as HIOKIST5520PLCEntity;
                    BusinessHandler(entity, value, judgeResult, judgeString);
                }
                stopwatch.Stop();
                this.RealShowMessage($"【{this.Name}】获取测量值，耗时：{stopwatch.ElapsedMilliseconds} 毫秒，测量值：{CommonHelper.GetScientificNotation(value)} MΩ，判定结果：{judgeString}", true);
            }
            else
            {
                StatusHandler(false);
                this.RealShowMessage($"【{this.Name}】仪器状态有问题", false);
            }
        }
    }
}
